Completed
Pull Request — master (#226)
by
unknown
34s
created

EAN13.js ➔ ???   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 22

Duplication

Lines 22
Ratio 100 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 4
c 4
b 0
f 0
nc 4
nop 2
dl 22
loc 22
rs 8.9197
1
// Encoding documentation:
2
// https://en.wikipedia.org/wiki/International_Article_Number_(EAN)#Binary_encoding_of_data_digits_into_EAN-13_barcode
3
4
import { SIDE_BIN, MIDDLE_BIN, EAN13_STRUCTURE } from './constants';
5
import encode from './encoder';
6
import Barcode from '../Barcode';
7
8
// Calculate the checksum digit
9
// https://en.wikipedia.org/wiki/International_Article_Number_(EAN)#Calculation_of_checksum_digit
10
const checksum = (number) => {
11
	const res = number
12
		.substr(0, 12)
13
		.split('')
14
		.map((n) => +n)
15
		.reduce((sum, a, idx) => {
16
			return idx % 2
17
				? sum + a * 3
18
				: sum + a;
19
		}, 0);
20
21
	return (10 - (res % 10)) % 10;
22
};
23
24
class EAN13 extends Barcode {
25
26
	constructor(data, options) {
27
		// Add checksum if it does not exist
28
		if (data.search(/^[0-9]{12}$/) !== -1) {
29
			data += checksum(data);
30
		}
31
32
		super(data, options);
33
34
		// Make sure the font is not bigger than the space between the guard bars
35
		this.fontSize = !options.flat && options.fontSize > options.width * 10
36
			? options.width * 10
37
			: options.fontSize;
38
39
		// Make the guard bars go down half the way of the text
40
		this.guardHeight = options.height + this.fontSize / 2 + options.textMargin;
41
42
		// Adds a last character to the end of the barcode
43
		this.lastChar = options.lastChar;
44
	}
45
46
	valid() {
47
		return (
48
			this.data.search(/^[0-9]{13}$/) !== -1 &&
49
			+this.data[12] === checksum(this.data)
50
		);
51
	}
52
53
	encode() {
54
		return this.options.flat
55
			? this.encodeFlat()
56
			: this.encodeGuarded();
57
	}
58
59
	get leftData() {
60
		return this.data.substr(1, 6);
61
	}
62
63
	get rightData() {
64
		return this.data.substr(7, 6);
65
	}
66
67
	// The "standard" way of printing EAN13 barcodes with guard bars
68
	encodeGuarded() {
69
		const textOptions = { fontSize: this.fontSize };
70
		const guardOptions = { height: this.guardHeight };
71
72
		const data = [
73
			{
74
				data: SIDE_BIN,
75
				options: guardOptions
76
			},
77
			{
78
				data: encode(this.leftData, EAN13_STRUCTURE[this.data[0]]),
79
				text: this.text.substr(1, 6),
80
				options: textOptions
81
			},
82
			{
83
				data: MIDDLE_BIN,
84
				options: guardOptions
85
			},
86
			{
87
				data: encode(this.rightData, 'RRRRRR'),
88
				text: this.text.substr(7, 6),
89
				options: textOptions
90
			},
91
			{
92
				data: SIDE_BIN,
93
				options: guardOptions
94
			},
95
		];
96
97
		if (this.options.displayValue) {
98
			data.unshift({
99
				data: '000000000000',
100
				text: this.text.substr(0, 1),
101
				options: { textAlign: 'left', ...textOptions }
102
			});
103
104
			if (this.options.lastChar) {
105
				data.push({
106
					data: '00'
107
				});
108
				data.push({
109
					data: '00000',
110
					text: this.options.lastChar,
111
					options: textOptions
112
				});
113
			}
114
		}
115
116
		return data;
117
	}
118
119
	encodeFlat() {
120
		const left = encode(this.leftData, EAN13_STRUCTURE[this.data[0]]);
121
		const right = encode(this.rightData, 'RRRRRR');
122
123
		return {
124
			data: [SIDE_BIN, left, MIDDLE_BIN, right, SIDE_BIN].join(''),
125
			text: this.text
126
		};
127
	}
128
129
}
130
131
export default EAN13;
132